我们接下来介绍函数式语言中3个常见的函数:Map,Filter,Reduce。

命令式代码与声明式代码

前面我们介绍了函数式编程中常见的几种函数,下面我们要开始转变观念了。

命令式代码的意思就是,我们通过编写一条又一条指令去让计算机执行一些动作,这其中一般都会涉及到很多繁杂的细节。 而声明式就要优雅很多了,我们通过写表达式的方式来声明我们想干什么,而不是通过一步一步的指示。

// 命令式
const makes = [];
for (i = 0; i < cars.length; i++) {
  makes.push(cars[i].make);
}

// 声明式
var makes = cars.map(function(car){ return car.make; });

我们看下es5 Map,Filter,Reduce函数的简单实现。

Array.prototype.map = function(f) {
    const newArray = [];
    const O = Object(this);
    for (let i = 0; i < O.length; i++) {
        newArray[i] = f(O[i]);
    }
    return newArray;
}


Array.prototype.filter = function(pred) {
    const newArray = [];
    for (var i = 0; i < this.length; ++i) {
        if (pred(this[i]))
            newArray[newArray.length] = this[i];
    }
    return newArray;
}

Array.prototype.reduce = function(f, start) {
    var acc = start;
    for (var i = 0; i < this.length; ++i)
        acc = f(this[i], acc); // f() 接受2个参数
    return acc;
};

这3个常见的函数会在我们函数式编程中经常出现的三个函数。
有一点需要说明的是,for循环是自然语言的处理结果,永远是比map快的。这个就需要你自己在编写代码的时候对利弊进行权衡。

一段函数式编程的综合应用

<!DOCTYPE html>
<html>
    <head>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.11/require.min.js"></script>
        <script>
            requirejs.config({
                paths: {
                    ramda: 'https://cdnjs.cloudflare.com/ajax/libs/ramda/0.13.0/ramda.min',
                    jquery: 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min'
                }
            });

            require([
                'ramda',
                'jquery'
                ],
                   (_, $) => {
                    const Impure = {
                        getJSON: _.curry((callback, url) => {
                            $.getJSON(url, callback);
                        }),

                        setHtml: _.curry((sel, html) => {
                            $(sel).html(html);
                        })
                    };

                    const img = url => $('<img />', { src: url });

                    const trace = _.curry((tag, x) => {
                      console.log(tag, x);
                      return x;
                    });

                    const url = t => 'https://api.flickr.com/services/feeds/photos_public.gne?tags=' + t + '&format=json&jsoncallback=?';

                    const mediaUrl = _.compose(_.prop('m'), _.prop('media'));

                    const srcs = _.compose(_.map(mediaUrl), _.prop('items'));

                    const images = _.compose(_.map(img), srcs);

                    const renderImages = _.compose(Impure.setHtml("body"), images);

                    const app = _.compose(Impure.getJSON(renderImages), url);

                    app("cats");
                }
            );
        </script>
    </head>
    <body></body>
</html>

林小新
371 声望11 粉丝

想写非常炫酷的3D效果